package com.zgy.myshellcommand.capabilities.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.csv.CsvReader;
import cn.hutool.core.text.csv.CsvRow;
import cn.hutool.core.text.csv.CsvUtil;
import com.zgy.myshellcommand.capabilities.WriteToExcel;
import com.zgy.myshellcommand.commandentity.FileToExcelEntity;
import com.zgy.myshellcommand.commandentity.SheetConfigEntity;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;


public class WriteToExcelImplByPoi implements WriteToExcel {

    public boolean writeToExcel(FileToExcelEntity fileToExcelEntity) {
        setInsertExcelStartRowAndCol(fileToExcelEntity);
        CsvReader csvReader = CsvUtil.getReader();
        BufferedInputStream inputStream=null;
        SXSSFWorkbook sxssfWorkbook=null;
        BufferedOutputStream outputStream = FileUtil.getOutputStream(fileToExcelEntity.getInsertExcel());
        try {
            if (Objects.nonNull(fileToExcelEntity.getModuleExcel())) {
                inputStream = FileUtil.getInputStream(fileToExcelEntity.getModuleExcel());
                sxssfWorkbook = new SXSSFWorkbook(new XSSFWorkbook(inputStream), fileToExcelEntity.getCommitRow());
                for (SheetConfigEntity sheetConfigEntity : fileToExcelEntity.getSheetConfigEntities()) {
                    SXSSFSheet sheet = sxssfWorkbook.getSheet(sheetConfigEntity.getSheetName());
                    sheetWrite(csvReader, sheetConfigEntity, sheet);
                }
                sxssfWorkbook.write(outputStream);
                sxssfWorkbook.close();
                outputStream.close();
                inputStream.close();
            }

            if (Objects.isNull(fileToExcelEntity.getModuleExcel())){
                sxssfWorkbook = new SXSSFWorkbook(new XSSFWorkbook(), fileToExcelEntity.getCommitRow());
                for (SheetConfigEntity sheetConfigEntity : fileToExcelEntity.getSheetConfigEntities()) {
                    SXSSFSheet sheet = sxssfWorkbook.createSheet(sheetConfigEntity.getSheetName());
                    sheetWrite(csvReader, sheetConfigEntity, sheet);
                }
                sxssfWorkbook.write(outputStream);
                sxssfWorkbook.close();
                outputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    private void setInsertExcelStartRowAndCol(FileToExcelEntity fileToExcelEntity) {
        for (SheetConfigEntity sheetConfigEntity : fileToExcelEntity.getSheetConfigEntities()) {
            for (int i = 0; i < sheetConfigEntity.getDataFileNumberTypeCols().size(); i++) {
                sheetConfigEntity.getDataFileNumberTypeCols().set(i, sheetConfigEntity.getExcelStartColNum() + sheetConfigEntity.getDataFileNumberTypeCols().get(i) + 1);
            }
        }
    }

    private void sheetWrite(CsvReader csvReader, SheetConfigEntity sheetConfigEntity, SXSSFSheet sheet) {
        csvReader.setFieldSeparator(sheetConfigEntity.getDataFileFieldSeparator().charAt(0));
        List<CsvRow> rows = csvReader.read(Paths.get(sheetConfigEntity.getDataFileName()), Charset.forName(sheetConfigEntity.getDataFileCharSet())).getRows();
        int rowNum = sheetConfigEntity.getExcelStartRowNum();
        for (CsvRow rowData : rows) {
            SXSSFRow row = sheet.createRow(rowNum++);
            int colNum = sheetConfigEntity.getExcelStartColNum();
            for (String col : rowData.getRawList()) {
                SXSSFCell cell = row.getCell(colNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                if (StringUtil.isNotBlank(col)){
                    if (sheetConfigEntity.getDataFileNumberTypeCols().contains(colNum)){
                        cell.setCellValue(Double.parseDouble(col.trim()));
                    }else {
                        cell.setCellValue(col);
                    }
                }
                colNum++;
            }
        }
    }
}
